home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Music Architecture / Mixed Bag / •Instrument Editor / IE KeyboardDiagram.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  4.7 KB  |  283 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        KeyboardDiagram.c
  3.  
  4.     Modified version from the one in the warhol project
  5.  
  6. */
  7.  
  8.  
  9. #include <Memory.h>
  10. #include <QuickDraw.h>
  11. #include <Resources.h>
  12. #include "IE KeyboardDiagram.h"
  13.  
  14. static Handle GetAndDetachResource(ResType type,short id);
  15.  
  16. #define kBlackKeyBottom 16
  17.  
  18. static Handle GetAndDetachResource(ResType type,short id)
  19.     {
  20.     Handle h;
  21.  
  22.     h = GetResource(type,id);
  23.     DetachResource(h);
  24.     return h;
  25.     }
  26.  
  27. void InitializeKeyboard(KeyboardDiagram *kd,Rect *r,short octaveCount,short lowKey)
  28.     {
  29.     short i;
  30.  
  31.     kd->r = *r;
  32.     kd->octaveCount = octaveCount;
  33.     kd->keyCount = octaveCount * 12;
  34.  
  35.     if(lowKey >= 128)
  36.         {
  37.         kd->mod = true;
  38.         kd->modOffset = ((lowKey + kd->keyCount - 1) / kd->keyCount) * kd->keyCount;
  39.         lowKey &= 127;
  40.         }
  41.     else
  42.         kd->mod = false;
  43.  
  44.     kd->lowKey = lowKey;
  45.  
  46.     for(i = 0; i < 128; i++)
  47.         kd->keyVel[i] = 0;
  48.  
  49.     kd->whiteKey = (short **)GetAndDetachResource('Junk',kJunkWhite);
  50.     kd->keyRight = (short **)GetAndDetachResource('Junk',kJunkBlack);
  51.     }
  52.  
  53. void TerminateKeyboard(KeyboardDiagram *kd)
  54.     {
  55.     DisposeHandle((Handle)kd->whiteKey);
  56.     DisposeHandle((Handle)kd->keyRight);
  57.     }
  58.  
  59. void SetKeyboardTopLeft(KeyboardDiagram *kd,short top, short left)
  60.     {
  61.     OffsetRect(&kd->r, left - kd->r.left, top - kd->r.top);
  62.     }
  63.  
  64. void DrawKeyboardPiece(KeyboardDiagram *kd, short octave)
  65.     {
  66.     Rect r;
  67.     short w;
  68.     PicHandle pH;
  69.  
  70.     PenNormal();
  71.  
  72.     pH = (PicHandle)Get1Resource('PICT',kKeyboardPict);
  73.     if(pH)
  74.         {
  75.         r = (**pH).picFrame;
  76.         w = r.right - r.left-1;
  77.         OffsetRect(&r,kd->r.left - r.left + w * octave,kd->r.top - r.top);
  78.         DrawPicture(pH,&r);
  79.     
  80.         if(kd->gray)
  81.             {
  82.             GoGray();
  83.             PenMode(patBic);
  84.             r.right += 2;
  85.             r.bottom += 2;
  86.             PaintRect(&r);
  87.             PenNormal();
  88.             }
  89.         }
  90.     }
  91.  
  92.  
  93. void DrawKeyboardDropShadow(KeyboardDiagram *kd)
  94.     {
  95.     MoveTo(kd->r.left + 3,kd->r.bottom);
  96.     LineTo(kd->r.right,kd->r.bottom);
  97.     LineTo(kd->r.right,kd->r.top + 3);
  98.     }
  99.  
  100. void DrawKeyboard(KeyboardDiagram *kd)
  101.     {
  102.     short i;
  103.  
  104.     DrawKeyboardDropShadow(kd);
  105.     for(i = 0; i < kd->octaveCount; i++)
  106.         DrawKeyboardPiece(kd,i);
  107.     }
  108.  
  109. void SetKeyboardGray(KeyboardDiagram *kd,Boolean gray)
  110.     {
  111.     if(kd->gray != gray)
  112.         {
  113.         kd->gray = gray;
  114.         DrawKeyboard(kd);
  115.         }
  116.     }
  117.  
  118.  
  119.  
  120. void PaintKeyboardKey(KeyboardDiagram *kd,short pitch,short gray)
  121. /* 
  122.  * 0-255, gray; -1, invert; -2, forecolor
  123.  */
  124.     {
  125.     short i,k;
  126.     short octave;
  127.     Rect r1,r2;
  128.     Boolean blackKey;
  129.  
  130.     if(kd->gray)
  131.         goto goHome;
  132.  
  133.  
  134.     r1.left = r1.right = 0;
  135.     r2.left = r2.right = 0;
  136.  
  137.     pitch -= kd->lowKey;
  138.     if(pitch < 0 || pitch >= kd->keyCount)
  139.         goto goHome;
  140.  
  141.     octave = pitch / 12;
  142.     pitch = pitch % 12;
  143.  
  144.     blackKey = false;
  145.  
  146.     if(pitch == 1 || pitch == 3
  147.             || pitch == 6 || pitch == 8 || pitch == 10)
  148.         {
  149.         /*
  150.          * Black Keys
  151.          */
  152.         blackKey = true;
  153.         r1.left = kd->r.left + (*kd->keyRight)[pitch - 1] + 2;
  154.         r1.top = kd->r.top + 3;
  155.         r1.right = kd->r.left + (*kd->keyRight)[pitch];
  156.         r1.bottom = kd->r.top + kBlackKeyBottom;
  157.         }
  158.     else
  159.         {
  160.         /*
  161.          * White Keys
  162.          */
  163.         k = kd->r.left + 2;
  164.         i = 0;
  165.         while((*kd->whiteKey)[i] != pitch)
  166.             {
  167.             i++;
  168.             k += 9;
  169.             }
  170.         r1.left = k;
  171.         r1.top = kd->r.top + kBlackKeyBottom + 2;
  172.         r1.right = k+6;
  173.         r1.bottom = kd->r.bottom - 1;
  174.  
  175.         if(pitch)
  176.             r2.left = kd->r.left + (*kd->keyRight)[pitch - 1] + 2;
  177.         else
  178.             r2.left = kd->r.left + 2;
  179.         r2.top = kd->r.top + 2;
  180.         r2.right = kd->r.left + (*kd->keyRight)[pitch];
  181.         r2.bottom = kd->r.top + kBlackKeyBottom + 2;
  182.  
  183.         /*
  184.          * This is cheesy and proves I have
  185.          * no idea what I am doing. - dvb
  186.          */
  187.         if(pitch == 5)
  188.             r2.left ++;
  189.         else if(pitch == 11)
  190.             r2.right --;
  191.         }
  192.  
  193.     OffsetRect(&r1,octave * 63,0);
  194.     OffsetRect(&r2,octave * 63,0);
  195.  
  196.     if(gray >=0)
  197.         {
  198.         RGBColor c;
  199.  
  200.         if(!blackKey)
  201.             gray = 255 - gray;
  202.         c.blue = c.green = c.red = (((unsigned short)gray)<<8) | gray;
  203.         RGBForeColor(&c);
  204.         }
  205.  
  206.     if(gray == -1)
  207.         {
  208.         InvertRect(&r1);
  209.         InvertRect(&r2);
  210.         }
  211.     else
  212.         {
  213.         PaintRect(&r1);
  214.         PaintRect(&r2);
  215.         }
  216. goHome:
  217.     ForeColor(blackColor);
  218.     PenNormal();
  219.     }
  220.  
  221.  
  222. void PaintKeyboardVector(KeyboardDiagram *kd,unsigned char *keyVel)
  223.     {
  224.     short i;
  225.     unsigned char *w1,*w2;
  226.     long x;
  227.  
  228.     w1 = keyVel;
  229.     w2 = kd->keyVel;
  230.     for(i = 0; i < 128; i++)
  231.         {
  232.         x = *w1;
  233.         if(*w2 != x)
  234.             {
  235.             *w2 = x;
  236.             x = x ? x+128:0;
  237.             if( (i < kd->lowKey) || (i >= (kd->lowKey + kd->keyCount)) )
  238.                 {
  239.                 if(kd->mod)
  240.                     PaintKeyboardKey(kd,
  241.                             (i+kd->modOffset)%(kd->keyCount)+kd->lowKey,x);
  242.                 }
  243.             PaintKeyboardKey(kd,i,x);
  244.             }
  245.         w1++;
  246.         w2++;
  247.         }
  248.     }
  249.  
  250.  
  251. short GetKeyboardKey(KeyboardDiagram *kd,Point p)
  252. /*
  253.  * Return -1 if outside rectangle.
  254.  */
  255.     {
  256.     short pitch,octave;
  257.  
  258.     if(PtInRect(p,&kd->r))
  259.         {
  260.         p.h -= kd->r.left;
  261.         p.v -= kd->r.top;
  262.  
  263.         octave = p.h / 63;
  264.         p.h %= 63;
  265.  
  266.         if(p.v > kBlackKeyBottom)
  267.             pitch = (*kd->whiteKey)[p.h/9];
  268.         else
  269.             {
  270.             pitch = 0;
  271.             while((*kd->keyRight)[pitch] < p.h)
  272.                 pitch++;
  273.             }
  274.         pitch += octave*12;
  275.         pitch += kd->lowKey;
  276.         }
  277.     else
  278.         pitch = -1;
  279.  
  280.     return pitch;
  281.     }
  282.  
  283.